package form_service

import (
	"shimmer/neusoft_club_backend/controllers/utils"
	"shimmer/neusoft_club_backend/dao/domain"
	"shimmer/neusoft_club_backend/services"
	cons2 "shimmer/neusoft_club_backend/services/errs"
	"time"
)

func PostForm(userID, formID int64, content *map[string]interface{}) (form *domain.ClubForm, application *domain.UserApplication, err error) {
	form, err = FindFormById(formID)
	if err != nil {
		return
	}
	if form.ClubID == nil {
		return nil, nil, cons2.ErrFormIsOrphan
	}
	if !form.AllowRepeat {
		applications := make([]domain.UserApplication, 0)
		err = services.DBEngine.Model(form).Association(domain.ClubFormColumnApplication).Find(&applications, services.DBEngine.Where("user_id=?", userID))
		if err != nil {
			return nil, nil, err
		}
		applicationsLen := len(applications)
		if applicationsLen > 0 {
			firstApplication := applications[0]
			if !form.AllowRewrite {
				return nil, nil, cons2.ErrFormNotAllowRewrite
			}
			// 如果存在下一次提交时间限制则比对时间
			if firstApplication.NextUpdateTime != nil && firstApplication.NextUpdateTime.Before(time.Now()) {
				return nil, nil, cons2.ErrFormNotAllowRewrite
			}
			firstApplication.Content = *content
			err = services.DBEngine.Save(firstApplication).Error
			if err != nil {
				return
			}
		} else {
			_, application, err = FormAppendApplication(userID, form, content)
			if err != nil {
				return
			}
		}
	} else {
		_, application, err = FormAppendApplication(userID, form, content)
		if err != nil {
			return
		}
	}
	return
}

func FormAppendApplication(userID int64, form *domain.ClubForm, content *map[string]interface{}) (status *domain.ClubFormStatusFlow, application *domain.UserApplication, err error) {
	status = &domain.ClubFormStatusFlow{}
	// 找到根状态
	//err = services.DBEngine.Where("club_id=? and parent_id is null", *form.ClubID).First(status).Error
	// 默认初始状态为草稿
	err = services.DBEngine.Where("type=?", domain.ClubFormStatusFlowTypeDraft).First(status).Error
	if err != nil {
		return
	}
	application = &domain.UserApplication{
		FormID:     &form.ID,
		UserID:     userID,
		StatusID:   &status.ID,
		Content:    *content,
		SourceForm: *form.Value,
	}
	if err = services.DBEngine.Save(application).Error; err != nil {
		return
	}
	application.Status = status
	//err = services.DBEngine.Model(form).Association(domain.ClubFormColumnApplication).Append(newApplication)
	return
}

func FindFormById(formID int64) (res *domain.ClubForm, err error) {
	res = &domain.ClubForm{ID: formID}
	err = services.DBEngine.First(res).Error
	return
}

func FindFormStatusFlow(formID int64) (headFlow *domain.ClubFormStatusFlow, err error) {
	flows := make([]*domain.ClubFormStatusFlow, 0)
	err = services.DBEngine.Where("form_id=?", formID).Find(&flows).Error
	if err != nil {
		return
	}
	if len(flows) == 0 {
		return
	}

	flowMap := make(map[int64]*domain.ClubFormStatusFlow, len(flows))
	for _, f := range flows {
		if f == nil {
			continue
		}
		flowMap[f.ID] = f
		if f.ParentID == nil {
			headFlow = f
		}
	}
	if headFlow != nil && len(flowMap) > 1 {
		for _, f := range flowMap {
			if f.ParentID != nil {
				parent := flowMap[*f.ParentID]
				if parent == nil {
					continue
				}
				parent.Children = append(parent.Children, f)
			}
		}
	}
	return
}

func FindUsersApplicationForForm(userID, formID int64, query *utils.PaginationQuery) (res utils.Pagination, err error) {
	applications := make([]domain.UserApplication, 0)
	res, err = utils.QueryAndPaginate(query, services.DBEngine.Where("user_id=? and form_id=?", userID, formID), &applications)
	return
}
